package com.yzg.sign.project.token;

import com.yzg.sign.project.domain.Customer;

import com.yzg.sign.project.exception.NormalException;
import com.yzg.sign.project.repository.CustomerRepository;
import com.yzg.sign.project.repository.SysUserRepository;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import sun.misc.BASE64Encoder;

import java.io.Serializable;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Optional;
import java.util.Random;
import java.util.concurrent.TimeUnit;


@Component
@Slf4j
public class TokenUtils
{
    private static final String TOKEN_PREFIX = "TOKEN:";

    private static final String USER_SURVIVE = "SURVIVE:";



    @Autowired
    private RedisTemplate<String, Serializable> redisCacheTemplate;

    @Autowired
    private SysUserRepository sysUserRepository;

    @Autowired
    private CustomerRepository customerRepository;




    /**
     * 根据token从redis获取用户
     * @return
     */
    public Customer getLoginUser(String token) {
        try {
            final Customer customer = (Customer) redisCacheTemplate.opsForValue().get(TOKEN_PREFIX + token);
            if (customer != null) {
              if ((TOKEN_PREFIX + token).equals(redisCacheTemplate.opsForValue().get(USER_SURVIVE + customer.getId()))) {
                    return customer;
              }
            }
        }catch (Exception e)
        {
            return null;
        }
        return null;
    }




    public void  changeToken(Customer customer)
    {
        redisCacheTemplate.opsForValue().set(USER_SURVIVE + customer.getId(), TOKEN_PREFIX );
    }






    /**
     * 根据token从redis获取用户
     * @return
     */
    public Customer getLoginUser() {
        String token = SecurityUtils.getSubject().getPrincipal().toString();
        return this.getLoginUser(token);
    }


    /**
     * @Method
     * @Author www
     * @Version  1.0
     * @Description 获取token
     * @Return
     * @Date 2019/9/27 10:06
     */
    public String getToken() {
        String token = SecurityUtils.getSubject().getPrincipal().toString();
        if (null == token) {
            throw new NormalException("token获取失败");
        }
        return token;
    }





    /**
     * 从数据库中查询
     * @return Customer
     */
    public Customer getUserInfo() {
        String token = SecurityUtils.getSubject().getPrincipal().toString();
        Customer loginUser = this.getLoginUser(token);
        if (null != loginUser) {
            Optional<Customer> sysUserOptional = customerRepository.findById(loginUser.getId());
            if (sysUserOptional.isPresent()) {
                Customer sysUser = sysUserOptional.get();
                return sysUser;
            }
        }
        return null;
    }
    /**
     * 生成token
     *
     * @param id
     * @return
     */
    public  <T>  String generateTokeCode(Serializable clazz, String id) {

        String value = System.currentTimeMillis() + new Random().nextInt() + "";
        //获取数据指纹，指纹是唯一的
        try {
            MessageDigest md = MessageDigest.getInstance("md5");
            byte[] b = md.digest(value.getBytes());//产生数据的指纹
            //Base64编码
            BASE64Encoder be = new BASE64Encoder();
            String key = be.encode(b);
            redisCacheTemplate.opsForValue().set(TOKEN_PREFIX + key, clazz);
            redisCacheTemplate.expire(TOKEN_PREFIX + key, 30, TimeUnit.DAYS);
            redisCacheTemplate.opsForValue().set(USER_SURVIVE + id, TOKEN_PREFIX + key);  //存活的token更新
            return key;
        } catch (NoSuchAlgorithmException e) {
            throw new NormalException("token生成失败");
       }
    }








}



